/*
 * @Author: 脉迈
 * @Date: 2021-09-15 17:50:35
 * @LastEditors: 脉迈
 * @LastEditTime: 2022-01-25 17:29:00
 */
import React, { Fragment, useEffect, useState } from "react";
import BlockImage from "plugins/blockImage/blockImage";
import BlockText from "plugins/blockText/blockText";
import BlockButton from "plugins/blockButton/blockButton";
import { transformProps, transformStyle } from "utils/helper";
import EditShape from "components/EditShape/Index";
import styles from "./EditorBox.module.scss";
import { Tooltip, message, Menu, Dropdown, Progress } from "antd";
import { blockData } from "data/componentItem";
import { PsdPercentStatus, uploadPsdStatus } from "store/modules/status";
import { useLocation } from "react-router-dom";
import {
  pageComponentsState,
  blockActiveIndexState,
  componentActiveIndexState,
} from "store/modules/element";

import { useRecoilState } from "recoil";

export default function Index() {
  const location = useLocation();
  const [renderList, setRenderList] = useState<any>([]);
  const [pageComponentList, setPageComponentList] =
    useRecoilState(pageComponentsState);
  const [blockActiveIndex, setBlockActiveIndex] = useRecoilState(
    blockActiveIndexState
  );
  const [componentActiveIndex, setComponentActiveIndex] = useRecoilState(
    componentActiveIndexState
  );
  const [PadPercent] = useRecoilState(PsdPercentStatus);
  const [uploadStatus] = useRecoilState(uploadPsdStatus);
  const [editorStatus, setEditor] = useState(false);

  /**
   * @description 根据后台返回的数据，动态渲染
   */
  const renderComponent = () => {
    return renderList.map((item: any, index: number) => {
      return (
        <div
          key={index}
          style={{
            ...transformStyle(item.style),
            overflow: "hidden",
            backgroundImage: `url(${item.style.backgroundImage})`,
          }}
          onClick={(e) => {
            e.stopPropagation();
            if (editorStatus) {
              setComponentActiveIndex(0);
              setBlockActiveIndex(index);
            }
          }}
          className={
            editorStatus && blockActiveIndex === index
              ? `${styles.componentActive}`
              : ""
          }
        >
          <div
            className={styles.moveBlock}
            onMouseDown={(e) => {
              handleMoveBlock(e, index);
            }}
          ></div>
          {renderComponentChildren(item, index)}
        </div>
      );
    });
  };
  /**
   *
   * @param e
   * @param index
   * @description 动态拖动改变模块高度
   */
  const handleMoveBlock = (
    e: React.MouseEvent<HTMLDivElement, MouseEvent>,
    index: number
  ) => {
    e.stopPropagation();
    e.preventDefault(); // Let's stop this event.
    let move = (e: any) => {
      let height = e.offsetY;
      let newPageComponentList = JSON.parse(JSON.stringify(pageComponentList));
      newPageComponentList[index].style.height = height;
      setPageComponentList(newPageComponentList);
    };
    let up = () => {
      document.removeEventListener("mousemove", move);
      document.removeEventListener("mouseup", up);
    };
    document.addEventListener("mousemove", move);
    document.addEventListener("mouseup", up);
  };
  /**
   *
   * @param value
   * @description 改变当前编辑文字模块
   */
  const handleChangeText = (value: string) => {
    console.log(value);
    let newPageComponentList = JSON.parse(JSON.stringify(pageComponentList));
    newPageComponentList[blockActiveIndex].children[
      componentActiveIndex
    ].properties.text.value = value;
    setPageComponentList(newPageComponentList);
  };

  const renderComponentItem = (item: any, props: any) => {
    if (item.name === "blockImage") {
      return <BlockImage {...props}></BlockImage>;
    } else if (item.name === "blockText") {
      return (
        <BlockText
          {...props}
          onChange={(value: string) => {
            handleChangeText(value);
          }}
        >
          {props}
        </BlockText>
      );
    } else if (item.name === "blockButton") {
      return <BlockButton {...props}>{props}</BlockButton>;
    }
  };

  const renderComponentChildren = (item: any, index: number) => {
    // eslint-disable-next-line
    return item.children.map((Citem: any, Cindex: number) => {
      const props = transformProps(Citem.properties);
      return (
        <EditShape
          style={{ ...transformStyle(Citem.style) }}
          key={Cindex}
          defaultStyle={Citem.style}
          active={componentActiveIndex === Cindex && blockActiveIndex === index}
          handleKeyPressProp={(e: any) => {
            setComponentLocation(e.keyCode);
          }}
          handleMousedownProp={() => {
            setComponentActiveIndex(Cindex);
            setBlockActiveIndex(index);
          }}
          handleElementMouseUpProp={() => {}}
          /**
           * @description 放大缩小
           */
          handlePointMoveProp={(style: any) => {
            let newComponentsList = JSON.parse(
              JSON.stringify(pageComponentList)
            );
            newComponentsList[blockActiveIndex].children[
              componentActiveIndex
            ].style = style;
            setPageComponentList(JSON.parse(JSON.stringify(newComponentsList)));
          }}
          handlePointMouseUpProp={() => {}}
          handleContextMenuProp={(props: { left: number; top: number }) => {
            // console.log(props);
          }}
          /**
           * @description 移动
           */
          handleElementMoveProp={(style: any) => {
            // 点击移动同步top和left样式
            let newComponentsList = JSON.parse(
              JSON.stringify(pageComponentList)
            );
            let oldStyle =
              newComponentsList[blockActiveIndex].children[Cindex].style;
            newComponentsList[blockActiveIndex].children[Cindex].style = {
              ...oldStyle,
              ...style,
            };

            setPageComponentList(JSON.parse(JSON.stringify(newComponentsList)));
          }}
        >
          <Dropdown
            overlay={
              <Menu style={{ width: "130px" }}>
                <Menu.Item
                  key="copy"
                  onClick={() => {
                    copyComponent();
                  }}
                >
                  复制
                </Menu.Item>
                <Menu.SubMenu title="排序">
                  <Menu.Item
                    onClick={() => {
                      moveZindex("up");
                    }}
                  >
                    {" "}
                    上移一层
                  </Menu.Item>
                  <Menu.Item
                    onClick={() => {
                      moveZindex("down");
                    }}
                  >
                    下移一层
                  </Menu.Item>
                  <Menu.Item
                    onClick={() => {
                      moveZindex("max");
                    }}
                  >
                    上移到顶层
                  </Menu.Item>
                  {/* <Menu.Item onClick={()=>{moveZindex('min')}}>下移到底层</Menu.Item> */}
                </Menu.SubMenu>
                <Menu.Item
                  key="delete"
                  onClick={() => {
                    deleteComponent();
                  }}
                >
                  删除
                </Menu.Item>
              </Menu>
            }
            trigger={["contextMenu"]}
          >
            <div style={{ height: "100%" }}>
              {renderComponentItem(Citem, {
                ...props,
                ...{ style: Citem.properStyle },
              })}
            </div>
          </Dropdown>
        </EditShape>
      );
    });
  };

  // 处理添加空模块
  const handleAddBlock = () => {
    setPageComponentList((pageComponentList) => [
      ...pageComponentList,
      blockData,
    ]);
    setBlockActiveIndex(pageComponentList.length);
    console.log(JSON.stringify(pageComponentList));
  };

  /**
   * @description 处理点击方向键，定位位置
   */
  const setComponentLocation = (code: number) => {
    let newPageComponentList = JSON.parse(JSON.stringify(pageComponentList));
    switch (code) {
      case 40:
        newPageComponentList[blockActiveIndex].children[
          componentActiveIndex
        ].style.top += 1;
        break;
      case 38:
        newPageComponentList[blockActiveIndex].children[
          componentActiveIndex
        ].style.top -= 1;
        break;
      case 37:
        newPageComponentList[blockActiveIndex].children[
          componentActiveIndex
        ].style.left -= 1;
        break;
      case 39:
        newPageComponentList[blockActiveIndex].children[
          componentActiveIndex
        ].style.left += 1;
        break;

      default:
        break;
    }
    setPageComponentList(newPageComponentList);
  };

  /**
   * @description 处理删除模块
   */
  const handleDeleteBlock = () => {
    if (pageComponentList.length === 1) {
      message.warning("只有一个模块不能删除");
      return;
    }
    let newPageComponentsState = JSON.parse(JSON.stringify(pageComponentList));

    newPageComponentsState.splice(blockActiveIndex, 1);

    setPageComponentList(newPageComponentsState);

    setBlockActiveIndex(blockActiveIndex === 0 ? 0 : blockActiveIndex - 1);
  };

  /**
   * @description 处理往下移动模块
   */
  const handleNextBlock = () => {
    let newPageComponentList = JSON.parse(JSON.stringify(pageComponentList));
    if (blockActiveIndex === newPageComponentList.length - 1) {
      message.warning("当前是最后一个无法下移");
      return;
    }
    // 在下一项插入该项
    newPageComponentList.splice(
      blockActiveIndex + 2,
      0,
      newPageComponentList[blockActiveIndex]
    );
    // 删除前一项
    newPageComponentList.splice(blockActiveIndex, 1);
    setPageComponentList(newPageComponentList);
    setBlockActiveIndex(blockActiveIndex + 1);
  };

  /**
   * @description 处理往上移动模块
   */
  const handlePrevBlock = () => {
    if (blockActiveIndex === 0) {
      message.warning("当前是第一个无法上移");
      return;
    }
    let newPageComponentList = JSON.parse(JSON.stringify(pageComponentList));

    //在上一项插入该项
    newPageComponentList.splice(
      blockActiveIndex - 1,
      0,
      newPageComponentList[blockActiveIndex]
    );
    //删除后一项
    newPageComponentList.splice(blockActiveIndex + 1, 1);
    setPageComponentList(newPageComponentList);
    setBlockActiveIndex(blockActiveIndex - 1);
  };

  /**
   * @description 删除组件
   */
  const deleteComponent = () => {
    let newPageComponentsState = JSON.parse(JSON.stringify(pageComponentList));

    newPageComponentsState[blockActiveIndex].children.splice(
      componentActiveIndex,
      1
    );

    setPageComponentList(newPageComponentsState);
    setComponentActiveIndex(0);
  };

  /**
   * @description 复制组件
   */
  const copyComponent = () => {
    let newPageComponentList = JSON.parse(JSON.stringify(pageComponentList));
    let componentElement = JSON.parse(
      JSON.stringify(
        newPageComponentList[blockActiveIndex]["children"][componentActiveIndex]
      )
    );
    componentElement.style.top = componentElement.style.top + 20;
    componentElement.style.left = componentElement.style.left + 20;
    newPageComponentList[blockActiveIndex]["children"].push(componentElement);
    setComponentActiveIndex(
      newPageComponentList[blockActiveIndex]["children"].length - 1
    );
    setPageComponentList(newPageComponentList);
  };

  /**
   * @description 移动层级
   */
  const moveZindex = (type: string) => {
    let newPageComponentList = JSON.parse(JSON.stringify(pageComponentList));
    let componentElement = JSON.parse(
      JSON.stringify(
        newPageComponentList[blockActiveIndex]["children"][componentActiveIndex]
      )
    );
    let children: any = JSON.parse(
      JSON.stringify(newPageComponentList[blockActiveIndex]["children"])
    );
    let maxIndex = 0;
    let minIndex = -1;
    switch (type) {
      case "up":
        componentElement.style.zIndex += 1;
        newPageComponentList[blockActiveIndex]["children"][
          componentActiveIndex
        ] = componentElement;
        setPageComponentList(newPageComponentList);
        break;

      case "down":
        componentElement.style.zIndex -= 1;
        newPageComponentList[blockActiveIndex]["children"][
          componentActiveIndex
        ] = componentElement;
        setPageComponentList(newPageComponentList);
        break;

      case "max":
        // eslint-disable-next-line
        children.map((item: any) => {
          if (item.style.zIndex > maxIndex) {
            maxIndex = item.style.zIndex;
          }
        });
        componentElement.style.zIndex = maxIndex + 1;
        newPageComponentList[blockActiveIndex]["children"][
          componentActiveIndex
        ] = componentElement;
        setPageComponentList(newPageComponentList);
        break;

      case "min":
        // eslint-disable-next-line
        children.map((item: any) => {
          if (item.style.zIndex < minIndex) {
            minIndex = item.style.zIndex;
          }
        });
        componentElement.style.zIndex = minIndex - 2;
        newPageComponentList[blockActiveIndex]["children"][
          componentActiveIndex
        ] = componentElement;
        setPageComponentList(newPageComponentList);
        break;

      default:
        break;
    }
  };

  useEffect(() => {
    setRenderList(pageComponentList);
    if (pageComponentList.length) {
      localStorage.setItem("data", JSON.stringify(pageComponentList));
    }
  }, [pageComponentList]);

  useEffect(() => {
    // 设置当前是编辑器还是预览页面
    setEditor(location.pathname.includes("editor"));
    // 默认加载缓存里面的页面
    if (localStorage.getItem("data")) {
      let pageComponentList: any = localStorage.getItem("data");
      setPageComponentList(JSON.parse(pageComponentList));
    }

    // eslint-disable-next-line
  }, []);

  return (
    <Fragment>
      {editorStatus ? (
        <div style={{ position: "relative" }}>
          <div className={styles.operation}>
            <Tooltip placement="right" title="上移">
              <i
                className={`${styles.icon} iconfont icon-shangyi`}
                onClick={(e) => {
                  e.preventDefault();
                  handlePrevBlock();
                }}
              ></i>
            </Tooltip>
            <Tooltip placement="right" title="下移">
              <i
                className={`${styles.icon} iconfont icon-xiayi`}
                onClick={(e) => {
                  e.preventDefault();
                  handleNextBlock();
                }}
              ></i>
            </Tooltip>
            <Tooltip placement="right" title="向下添加模块">
              <i
                className={`${styles.icon} iconfont icon-tianjia1`}
                onClick={(e) => {
                  e.preventDefault();
                  handleAddBlock();
                }}
              ></i>
            </Tooltip>
            <Tooltip placement="right" title="删除">
              <i
                className={`${styles.icon} iconfont icon-icon`}
                onClick={(e) => {
                  e.preventDefault();
                  handleDeleteBlock();
                }}
              ></i>
            </Tooltip>
          </div>
          <div className={styles.main}>
            <div
              className={styles.uploadLoading}
              style={{ display: `${uploadStatus ? "block" : "none"}` }}
            >
              <Progress
                percent={PadPercent}
                status="active"
                className={styles.progressBar}
                showInfo={false}
              ></Progress>
            </div>
            <div className={styles.page} id="canvas-panel">
              {renderComponent()}
            </div>
          </div>
        </div>
      ) : (
        <div>{renderComponent()}</div>
      )}
    </Fragment>
  );
}
